package com.yipei.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yipei.business.domain.*;
import com.yipei.business.mapper.MlTradingGroupMapper;
import com.yipei.business.service.*;
import com.yipei.business.vo.EntrustOrderVo;
import com.yipei.business.vo.MlKLineMasterVo;
import com.yipei.business.vo.OptionalSymbolVo;
import com.yipei.business.vo.PositionShareVo;
import com.yipei.common.core.domain.AjaxResult;
import com.yipei.common.core.domain.entity.MlTradeAccount;
import com.yipei.common.core.domain.entity.SysUser;
import com.yipei.common.core.domain.model.LoginUser;
import com.yipei.common.utils.DateUtils;
import com.yipei.common.utils.SecurityUtils;
import com.yipei.common.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 交易群主Service业务层处理
 *
 * @author yipei
 * @date 2025-06-25
 */
@Service
public class MlTradingGroupServiceImpl extends ServiceImpl<MlTradingGroupMapper, MlTradingGroup> implements IMlTradingGroupService {
    @Autowired
    private MlTradingGroupMapper mlTradingGroupMapper;
    @Autowired
    private IMlTradeDealOrderService iMlTradeDealOrderService;
    @Autowired
    private IMlAssetFlowService iMlAssetFlowService;
    @Autowired
    private IMlPositionShareService iMlPositionShareService;
    @Autowired
    private IMlOptionalSymbolService iMlOptionalSymbolService;

    @Autowired
    private IMlDailySettlementInfoService iMlDailySettlementInfoService;

    @Autowired
    private IMlTodayProfitService iMlTodayProfitService;
    @Autowired
    private IMlTradeEntrustOrderService iMlTradeEntrustOrderService;
    @Autowired
    private IMlRealNameService iMlRealNameService;

    @Autowired
    private IMlTradeAccountService iMlTradeAccountService;

    @Autowired
    private MlTradeEntrustOrderServiceImpl mlTradeEntrustOrderService;

    @Autowired
    private MlTradeDealOrderServiceImpl mlTradeDealOrderServiceimpl;

    @Autowired
    private IMlBtsPointService iMlBtsPointService;

    /**
     * 查询交易群主
     *
     * @param id 交易群主主键
     * @return 交易群主
     */
    @Override
    public MlTradingGroup selectMlTradingGroupById(Long id) {
        return mlTradingGroupMapper.selectMlTradingGroupById(id);
    }

    /**
     * 查询交易群主列表
     *
     * @param mlTradingGroup 交易群主
     * @return 交易群主
     */
    @Override
    public List<MlTradingGroup> selectMlTradingGroupList(MlTradingGroup mlTradingGroup) {
        return mlTradingGroupMapper.selectMlTradingGroupList(mlTradingGroup);
    }

    /**
     * 新增交易群主
     *
     * @param mlTradingGroup 交易群主
     * @return 结果
     */
    @Override
    public int insertMlTradingGroup(MlTradingGroup mlTradingGroup) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        mlTradingGroup.setCreateTime(DateUtils.getNowDate());
        mlTradingGroup.setCreateBy(user.getUserName());
        return mlTradingGroupMapper.insertMlTradingGroup(mlTradingGroup);
    }

    /**
     * 修改交易群主
     *
     * @param mlTradingGroup 交易群主
     * @return 结果
     */
    @Override
    public int updateMlTradingGroup(MlTradingGroup mlTradingGroup) {
        mlTradingGroup.setUpdateTime(DateUtils.getNowDate());
        return mlTradingGroupMapper.updateMlTradingGroup(mlTradingGroup);
    }

    /**
     * 批量删除交易群主
     *
     * @param ids 需要删除的交易群主主键
     * @return 结果
     */
    @Override
    public int deleteMlTradingGroupByIds(Long[] ids) {
        return mlTradingGroupMapper.deleteMlTradingGroupByIds(ids);
    }

    /**
     * 删除交易群主信息
     *
     * @param id 交易群主主键
     * @return 结果
     */
    @Override
    public int deleteMlTradingGroupById(Long id) {
        return mlTradingGroupMapper.deleteMlTradingGroupById(id);
    }

    @Override
    public int addGroupUser(MlTradingGroup mlTradingGroup) {

        return this.insertMlTradingGroup(mlTradingGroup);
    }

    @Override
    public void createpositionShareData(List<PositionShareVo> positionShareVoList, List<MlPositionShare> mlPositionShares, MlTradeAccount mlTradeAccount) throws IOException {
        PositionShareVo positionShareVo = new PositionShareVo();
        positionShareVo.setCash(mlTradeAccount.getCash());
        positionShareVo.setTd_acc(mlTradeAccount.getTdAcc());
        positionShareVo.setCost(mlTradeAccount.getCost());
        positionShareVo.setLock(mlTradeAccount.getDjCash());
        BigDecimal z_sz = BigDecimal.ZERO;
        BigDecimal fd_yk = BigDecimal.ZERO;
        BigDecimal dr_yk = BigDecimal.ZERO;
        BigDecimal z_zc = BigDecimal.ZERO;
        for (MlPositionShare positionShare : mlPositionShares) {
            OptionalSymbolVo optionalSymbolVo = new OptionalSymbolVo();
            List<OptionalSymbolVo> optionalList = iMlOptionalSymbolService.createOptionalList(positionShare.getSymbol(), optionalSymbolVo);
            if (!CollectionUtils.isEmpty(optionalList)) {
                positionShare.setPrice(optionalList.get(0).getPrice());
                positionShare.setSec_name(optionalList.get(0).getSec_name());
                positionShare.setF12(optionalList.get(0).getF12());
                positionShare.setF14(optionalList.get(0).getF14());
                positionShare.setRatio(optionalList.get(0).getRatio());
            }
            positionShare.setCcDh(positionShare.getCcDh());
            positionShare.setYh_yl(positionShare.getYhYl());
            positionShare.setKy_cw(positionShare.getKyCw());
            positionShare.setCost(positionShare.getCbJj());
            positionShare.setAmount(positionShare.getKyCw().multiply(new BigDecimal(positionShare.getPrice())));
            BigDecimal cwSum = positionShare.getKyCw() == null ? BigDecimal.ZERO : positionShare.getKyCw().add(positionShare.getSdCw() == null ? BigDecimal.ZERO : positionShare.getSdCw().add(positionShare.getJrCw() == null ? BigDecimal.ZERO : positionShare.getJrCw()));
            z_sz = z_sz.add(cwSum.multiply(new BigDecimal(positionShare.getPrice())));
            fd_yk = fd_yk.add(cwSum.multiply(new BigDecimal(positionShare.getPrice()).subtract(positionShare.getCbJj())).add(positionShare.getYhYl() == null ? BigDecimal.ZERO : positionShare.getYhYl()));
        }

        LambdaQueryWrapper<MlDailySettlementInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.and(i -> i.eq(MlDailySettlementInfo::getTdAcc, mlTradeAccount.getTdAcc())
        );
        List<MlDailySettlementInfo> mlDailySettlementInfos = iMlDailySettlementInfoService.list(lambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(mlDailySettlementInfos)) {
            z_zc = mlDailySettlementInfos.get(0).getZZc();
        }
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String now = formatter.format(date);
        MlTodayProfit one = iMlTodayProfitService.lambdaQuery().eq(MlTodayProfit::getTdAcc, mlTradeAccount.getTdAcc()).eq(MlTodayProfit::getTdDay, now).one();
        if (one != null) {
            dr_yk = one.getProfit();
        }
        MlRealName realName = iMlRealNameService.lambdaQuery().eq(MlRealName::getTdAcc, mlTradeAccount.getTdAcc()).one();
        if (!ObjectUtils.isEmpty(realName)) {
            positionShareVo.setName(realName.getZsMz());
        }
        positionShareVo.setZ_sz(z_sz);
        positionShareVo.setFd_yk(fd_yk);
        positionShareVo.setDr_yk(dr_yk);
        positionShareVo.setKq_zj(mlTradeAccount.getKqZj());
        positionShareVo.setP_list(mlPositionShares);
        List<MlTradeEntrustOrder> mlTradeEntrustOrders = iMlTradeEntrustOrderService.lambdaQuery().eq(MlTradeEntrustOrder::getTdAcc, mlTradeAccount.getTdAcc()).list();
        positionShareVo.setMlTradeEntrustOrderList(mlTradeEntrustOrders);
        positionShareVoList.add(positionShareVo);
    }

    @Override
    @Transactional
    public AjaxResult addEntrustOrderGroup(EntrustOrderVo entrustOrderVo) throws Exception {
        LocalTime now = LocalTime.now();
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endtime1 = LocalTime.of(11, 30);
        LocalTime startTime1 = LocalTime.of(13, 0);
        LocalTime endTime = LocalTime.of(15, 0);
//        if (now.isAfter(startTime)&&now.isBefore(endtime1) &&now.isAfter(startTime1)&&now.isBefore(endTime)) {
        MlTradeEntrustOrder mlTradeEntrustOrder = entrustOrderVo.getMlTradeEntrustOrder();
        MlKLineMasterVo mlKLineMasterVo = entrustOrderVo.getMlKLineMasterVo();
//        mlTradeEntrustOrder.setSecName(mlKLineMasterVo.getF14());
        LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, mlTradeEntrustOrder.getTdAcc());
        MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
        if (mlTradeAccount.getFFive() == null) {
            throw new Exception(mlTradeAccount.getTdAcc() + "请先配配置是否免五");
        }
        if (mlTradeAccount.getBuyRate() == null || mlTradeAccount.getSellRate() == null) {
            throw new Exception(mlTradeAccount.getTdAcc() + "请先配配置手续费费率");
        }
        BigDecimal wtJg = mlTradeEntrustOrder.getWtJg();
        String wt = mlTradeEntrustOrderService.createrDH("WT");
        mlTradeEntrustOrder.setWtDh(wt);
        String tdAcc = mlTradeAccount.getTdAcc();
        BigDecimal cash = mlTradeAccount.getCash();
        mlTradeEntrustOrder.setTdAcc(tdAcc);
        int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
        mlTradeEntrustOrder.setChSjc((long) randomNumber);
        if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.valueOf(0)) == 0) {
            if (StringUtils.isEmpty(mlKLineMasterVo.getUpper_limit())) {
                mlKLineMasterVo.setUpper_limit("0");
            }
            if (wtJg.compareTo(new BigDecimal(mlKLineMasterVo.getUpper_limit())) >= 0) {
                return AjaxResult.error("买入价格超出涨停价");
            }
            if (wtJg.multiply(mlTradeEntrustOrder.getWtSl()).compareTo(cash) > 0 && wtJg.multiply(mlTradeEntrustOrder.getWtSl()).compareTo(mlTradeAccount.getDjCash()) > 0) {
                return AjaxResult.error(mlTradeAccount.getTdAcc() + "资金不足");
            }
            mlTradeEntrustOrderService.createMlpositionShare(mlTradeEntrustOrder, tdAcc);
            this.createDealOrder(mlTradeEntrustOrder, wtJg, cash, wtJg, mlTradeAccount);
        } else {
            if (StringUtils.isEmpty(mlKLineMasterVo.getLower_limit())) {
                mlKLineMasterVo.setUpper_limit("0");
            }
            if (wtJg.compareTo(new BigDecimal(mlKLineMasterVo.getLower_limit())) <= 0) {
                return AjaxResult.error("卖出价格低于跌停价价");
            }
            LocalDate date = LocalDateTime.now().toLocalDate();
            LambdaQueryWrapper<MlPositionShare> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.and(i -> i.eq(MlPositionShare::getTdAcc, tdAcc).eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol()).lt(MlPositionShare::getCreateTime, date)
            );
            List<MlPositionShare> mlPositionShares = iMlPositionShareService.list(lambdaQueryWrapper);
            BigDecimal zKycw = mlPositionShares.stream().map(MlPositionShare::getKyCw).reduce(BigDecimal.ZERO, BigDecimal::add);
//            MlPositionShare mlPositionShare = iMlPositionShareService.getOne(lambdaQueryWrapper);
            if (CollectionUtils.isEmpty(mlPositionShares)) {
                throw new Exception(mlTradeEntrustOrder.getTdAcc() + "账号下没有" + mlTradeEntrustOrder.getSecName() + "股票持仓");
            }
            if (mlTradeEntrustOrder.getWtSl().compareTo(zKycw) > 0) {
                return AjaxResult.error(mlTradeAccount.getTdAcc() + "中股票" + mlTradeEntrustOrder.getSecName() + "可用仓位不足");
            }
            mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().add(wtJg.multiply(mlTradeEntrustOrder.getWtSl())));
            mlTradeEntrustOrder.setWtZt(BigDecimal.valueOf(1));
            this.createDealOrderGroup(mlTradeEntrustOrder, mlTradeEntrustOrder.getWtJg(), String.valueOf(mlTradeEntrustOrder.getWtSl()), System.currentTimeMillis());
        }
//        mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
        return AjaxResult.success(mlTradeEntrustOrderService.insertMlTradeEntrustOrder(mlTradeEntrustOrder));
//        }
//        else {
//            throw new Exception("不在交易时间范围内");
//        }
    }

    private AjaxResult createDealOrderGroup(MlTradeEntrustOrder mlTradeEntrustOrder, BigDecimal cjJg, String cjSl, long cjSj) {

        //entrust_deal
        if (cjJg.compareTo(BigDecimal.ZERO) == 0 || StringUtils.isEmpty(cjSl)) {
            return AjaxResult.error("成交价格或成交数量不能为空！");
        } else if (cjJg.compareTo(BigDecimal.ZERO) == 0 || BigDecimal.valueOf(cjSj).compareTo(new BigDecimal(100)) < 0) {
            return AjaxResult.error("成交价格胃口或成交数量小于100！");
        }
        //
        if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(BigDecimal.ZERO) == 0) {
            mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
            iMlTradeEntrustOrderService.updateById(mlTradeEntrustOrder);
            iMlTradeDealOrderService.accountMessage(mlTradeEntrustOrder);
        }
        MlTradeAccount mlTradeAccount = iMlTradeAccountService.lambdaQuery().eq(MlTradeAccount::getTdAcc, mlTradeEntrustOrder.getTdAcc()).one();
        if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ZERO) == 0) {
            if (cjJg.compareTo(BigDecimal.ZERO) == 0 || cjSl.equals("0")) {
                return AjaxResult.error("成交价格或成交数量不能为空！");
            }
            if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(new BigDecimal(cjSl)) > 0 && new BigDecimal(100).compareTo(mlTradeEntrustOrder.getSySl()) >= 0) {
                cjSl = String.valueOf(mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl());
            }
            BigDecimal sxf = mlTradeDealOrderServiceimpl.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), cjSl, cjJg);
            MlPositionShare ps = iMlPositionShareService.lambdaQuery().eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol())
                    .eq(MlPositionShare::getTdAcc, mlTradeEntrustOrder.getTdAcc()).eq(MlPositionShare::getWtDh, mlTradeEntrustOrder.getWtDh()).one();
            if (ps == null) {
                ps = new MlPositionShare();
            }
            BigDecimal cc_sl = (ps.getKyCw() == null ? BigDecimal.ZERO : ps.getKyCw()).add(ps.getSdCw() == null ? BigDecimal.ZERO : ps.getSdCw()).add(ps.getJrCw() == null ? BigDecimal.ZERO : ps.getJrCw());
            ps.setCbJj(cc_sl.multiply(ps.getCbJj() == null ? BigDecimal.ZERO : ps.getCbJj()).add(cjJg.multiply(new BigDecimal(cjSl))));
            BigDecimal profit = (cjJg.subtract(ps.getCbJj() == null ? BigDecimal.ZERO : ps.getCbJj())).multiply(new BigDecimal(cjSl)).subtract(sxf);
            ps.setYhYl(ps.getYhYl() == null ? BigDecimal.ZERO : ps.getYhYl().subtract(sxf));
            ps.setJrCw(ps.getJrCw() == null ? BigDecimal.ZERO : ps.getJrCw().add(new BigDecimal(cjSl)));
            ps.setTdAcc(mlTradeEntrustOrder.getTdAcc());
            ps.setSymbol(mlTradeEntrustOrder.getSymbol());
            ps.setSec_name(mlTradeEntrustOrder.getSecName());
            ps.setCreateTime(new Date());
            iMlPositionShareService.saveOrUpdate(ps);
            mlTradeAccount.setCash(mlTradeAccount.getCash().add((mlTradeEntrustOrder.getWtJg().subtract(cjJg)).multiply(new BigDecimal(cjSl)).subtract(sxf)));
//            mlTradeAccount.setALock(mlTradeAccount.getALock().subtract(mlTradeEntrustOrder.getWtJg().multiply(new BigDecimal(cjSl))));
            iMlTradeAccountService.updateById(mlTradeAccount);
            if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(new BigDecimal(cjSl)) > 0) {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(2));
            }
            if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(new BigDecimal(cjSl)) == 0) {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
            }
            mlTradeDealOrderServiceimpl.accountMessage(mlTradeEntrustOrder);
            mlTradeEntrustOrder.setSySl((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).add(new BigDecimal(cjSl)));
            iMlTradeEntrustOrderService.updateById(mlTradeEntrustOrder);
            // 创建成交单
            mlTradeDealOrderServiceimpl.dealOrderCreateObject(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtDh(), mlTradeEntrustOrder.getSymbol(), mlTradeEntrustOrder.getWtFx(), cjJg, cjSl, sxf, sxf.multiply(new BigDecimal(-1)), cjSj, mlTradeEntrustOrder.getSecName());

            //添加日K标识
            iMlBtsPointService.createBtsToTrading(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getSymbol(), 0);
            iMlTodayProfitService.changeProfit(mlTradeEntrustOrder.getTdAcc(), sxf.multiply(new BigDecimal(-1)));
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 2, cjJg.multiply(new BigDecimal(cjSl)).multiply(new BigDecimal(-1)));
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 4, sxf.multiply(new BigDecimal(-1)));
        } else if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ONE) == 0) {
            LocalDate date = LocalDateTime.now().toLocalDate();
            List<MlPositionShare> mlPositionShares = iMlPositionShareService.lambdaQuery()
                 .eq(MlPositionShare::getTdAcc, mlTradeEntrustOrder.getTdAcc())
                            .eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol())
                            .lt(MlPositionShare::getCreateTime, date).orderByAsc(MlPositionShare::getCreateTime).list();
            BigDecimal sxf = iMlTradeDealOrderService.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), cjSl, cjJg);
            BigDecimal profit = this.sellStock(mlPositionShares, mlTradeEntrustOrder, mlTradeEntrustOrder.getWtSl(), mlTradeEntrustOrder.getWtJg(), sxf);
            //资金变更
            iMlTradeEntrustOrderService.setSellSymbolData(mlTradeAccount, cjJg, cjSl, sxf);
            iMlTradeAccountService.updateById(mlTradeAccount);
            //创建成交单
            mlTradeDealOrderServiceimpl.dealOrderCreateObject(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtDh(), mlTradeEntrustOrder.getSymbol(), mlTradeEntrustOrder.getWtFx(), cjJg, cjSl, sxf, profit, cjSj, mlTradeEntrustOrder.getSecName());
            //添加日K标识
            iMlBtsPointService.createBtsToTrading(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getSymbol(), 1);
            //记录当日盈亏
            iMlTodayProfitService.changeProfit(mlTradeEntrustOrder.getTdAcc(), profit);
            //记录流水
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 3, cjJg.multiply(new BigDecimal(cjSl)));
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 4, sxf.multiply(new BigDecimal(-1)));
            //委托变更
            if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(new BigDecimal(cjSl)) > 0) {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(2));
            } else if ((mlTradeEntrustOrder.getSySl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getSySl()).compareTo(new BigDecimal(cjSl)) == 0) {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
            }
            mlTradeDealOrderServiceimpl.accountMessage(mlTradeEntrustOrder);
        }
        return null;
    }

    private BigDecimal sellStock(List<MlPositionShare> mlPositionShares, MlTradeEntrustOrder mlTradeEntrustOrder, BigDecimal wtsl, BigDecimal wtJg, BigDecimal sxf) {
        BigDecimal remaining = wtsl;
        BigDecimal totalProfit = BigDecimal.ZERO;

        List<MlPositionShare> usedPositions = new ArrayList<>();
        List<BigDecimal> soldQtyList = new ArrayList<>();
        List<BigDecimal> profitList = new ArrayList<>();

        for (MlPositionShare pos : mlPositionShares) {
            if (remaining.compareTo(BigDecimal.ZERO) <= 0) break;

            BigDecimal kyCw = pos.getKyCw() != null ? pos.getKyCw() : BigDecimal.ZERO;
            if (kyCw.compareTo(BigDecimal.ZERO) <= 0) continue;

            BigDecimal sellQty = kyCw.min(remaining);
            BigDecimal cbJj = pos.getCbJj() != null ? pos.getCbJj() : BigDecimal.ZERO;
            BigDecimal profit = wtJg.subtract(cbJj).multiply(sellQty);

            // 更新持仓可用仓位
            pos.setKyCw(kyCw.subtract(sellQty));

            // 缓存数据用于后续分摊手续费
            usedPositions.add(pos);
            soldQtyList.add(sellQty);
            profitList.add(profit);
            totalProfit = totalProfit.add(profit);
            remaining = remaining.subtract(sellQty);
            mlTradeEntrustOrder.setSySl(pos.getKyCw());

        }

        // 如果持仓不足
        if (remaining.compareTo(BigDecimal.ZERO) > 0) {
            System.out.println("⚠️ 持仓不足，剩余未卖出：" + remaining);
        }

        // 分摊手续费并更新每条已获盈利
        for (int i = 0; i < usedPositions.size(); i++) {
            MlPositionShare pos = usedPositions.get(i);
            BigDecimal profit = profitList.get(i);
            BigDecimal ratio = (totalProfit.compareTo(BigDecimal.ZERO) == 0)
                    ? BigDecimal.ZERO
                    : profit.divide(totalProfit, 8, RoundingMode.HALF_UP);

            BigDecimal feePart = sxf.multiply(ratio).setScale(2, RoundingMode.HALF_UP);
            BigDecimal netProfit = profit.subtract(feePart);

            BigDecimal oldYl = pos.getYhYl() != null ? pos.getYhYl() : BigDecimal.ZERO;
            pos.setYhYl(oldYl.add(netProfit));
        }
        iMlPositionShareService.updateBatchById(usedPositions);
        // 返回总净利润
        return totalProfit.subtract(sxf).setScale(2, RoundingMode.HALF_UP);
    }

    @Override
    public List<MlTradeDealOrder> splitRecursively(MlTradeDealOrder mlTradeDealOrder) {
        List<MlTradeDealOrder> result = new ArrayList<>();
        this.splitInternal(mlTradeDealOrder, result);
        return result;
    }

    @Override
    public void splitInternal(MlTradeDealOrder order, List<MlTradeDealOrder> result) {
        BigDecimal amount = order.getCjJg().multiply(order.getCjSl());
        if (amount.compareTo(new BigDecimal(200000)) <= 0) {
            result.add(order);
            return;
        }

        // 继续拆单
        BigDecimal originalSl = order.getCjSl();
        BigDecimal halfSl = originalSl.divide(new BigDecimal("2"), 0, RoundingMode.DOWN);
        BigDecimal otherHalfSl = originalSl.subtract(halfSl);

        BigDecimal halfSxf = order.getCjSxf().divide(new BigDecimal("2"), 2, RoundingMode.HALF_UP);
        BigDecimal otherHalfSxf = order.getCjSxf().subtract(halfSxf);

        BigDecimal halfLr = order.getCjLr()==null?BigDecimal.ZERO:order.getCjLr().divide(new BigDecimal("2"), 2, RoundingMode.HALF_UP);
        BigDecimal otherHalfLr = order.getCjLr()==null?BigDecimal.ZERO:order.getCjLr().subtract(halfLr);
        // 创建第一笔
        MlTradeDealOrder first = new MlTradeDealOrder();
        BeanUtils.copyProperties(order, first);
        first.setCjDh(mlTradeDealOrderServiceimpl.createDealDh());
        first.setCjSl(halfSl);
        first.setCjSxf(halfSxf);
        first.setCjLr(halfLr);
        first.setSecName(order.getSecName());
        // 创建第二笔
        MlTradeDealOrder second = new MlTradeDealOrder();
        BeanUtils.copyProperties(order, second);
        second.setCjDh(mlTradeDealOrderServiceimpl.createDealDh());
        second.setCjSl(otherHalfSl);
        second.setCjSxf(otherHalfSxf);
        second.setCjLr(otherHalfLr);
        // 递归处理两笔
        splitInternal(first, result);
        splitInternal(second, result);
    }

    private void createDealOrder(MlTradeEntrustOrder mlTradeEntrustOrder, BigDecimal bid_p, BigDecimal cash, BigDecimal wtJg, MlTradeAccount mlTradeAccount) throws Exception {
        MlTradeDealOrder mlTradeDealOrder = new MlTradeDealOrder();
        mlTradeDealOrder.setCreateTime(new Date());
        mlTradeDealOrder.setWtDh(mlTradeEntrustOrder.getWtDh());
        mlTradeDealOrder.setCjDh(mlTradeEntrustOrderService.createDealDh());
        mlTradeDealOrder.setSymbol(mlTradeEntrustOrder.getSymbol());
        mlTradeDealOrder.setTdAcc(mlTradeEntrustOrder.getTdAcc());
        mlTradeDealOrder.setCjJg(mlTradeEntrustOrder.getWtJg());
        mlTradeDealOrder.setCjFx(mlTradeEntrustOrder.getWtFx());
        mlTradeDealOrder.setCjJg(bid_p);
        mlTradeDealOrder.setCjSl(mlTradeEntrustOrder.getWtSl());
        mlTradeDealOrder.setCjSj(System.currentTimeMillis());
        mlTradeDealOrder.setSecName(mlTradeEntrustOrder.getSecName());
        BigDecimal sxf = mlTradeEntrustOrderService.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeDealOrder.getCjSl(), mlTradeDealOrder.getCjJg());
        mlTradeDealOrder.setCjSxf(sxf);
        List<MlTradeDealOrder> resultList = this.splitRecursively(mlTradeDealOrder);
        for (MlTradeDealOrder tradeDealOrder : resultList) {
            iMlTradeDealOrderService.save(tradeDealOrder);
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 2, tradeDealOrder.getCjJg().multiply(tradeDealOrder.getCjSl()).multiply(new BigDecimal(-1)));
        }
        iMlBtsPointService.createBtsToTrading(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getSymbol(), 0);
        iMlTodayProfitService.changeProfit(mlTradeEntrustOrder.getTdAcc(), sxf.multiply(new BigDecimal(-1)));
        iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 4, sxf.multiply(new BigDecimal(-1)));
        /**
         * 买入扣款
         */
        mlTradeEntrustOrderService.mlTradeAccountSetData(mlTradeAccount, wtJg, mlTradeEntrustOrder.getWtSl(), sxf);
        iMlTradeAccountService.updateById(mlTradeAccount);
    }
}
